package aiku.numericalcontroloa.Service.Impl;

import aiku.numericalcontroloa.Base.Utils.BaseEnum;
import aiku.numericalcontroloa.Base.Utils.HttpStatus;
import aiku.numericalcontroloa.Base.Utils.Result;
import aiku.numericalcontroloa.Mapper.*;
import aiku.numericalcontroloa.Mapper.MasterControl.MessageNotificationMapper;
import aiku.numericalcontroloa.Model.Dto.PurchasePartDto;
import aiku.numericalcontroloa.Model.Dto.PurchaseReceiptsDto;
import aiku.numericalcontroloa.Model.Entity.*;
import aiku.numericalcontroloa.Model.Entity.MasterControl.MessageNotification;
import aiku.numericalcontroloa.Model.Vo.PurchaseInfoVo;
import aiku.numericalcontroloa.Model.Vo.PurchaseOrdersVo;
import aiku.numericalcontroloa.Model.Vo.PurchasePageInfoVo;
import aiku.numericalcontroloa.Model.Vo.PurchaseReceiptsVo;
import aiku.numericalcontroloa.Service.ProductsService;
import aiku.numericalcontroloa.Service.PurchaseOrdersService;
import aiku.numericalcontroloa.Task.NormalTask;
import aiku.numericalcontroloa.common.utils.DateUtils;
import aiku.numericalcontroloa.enums.RoleEnum;
import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import aiku.numericalcontroloa.Service.PurchaseReceiptsService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
* @author 马
* @description 针对表【purchase_receipts】的数据库操作Service实现
* @createDate 2024-02-27 11:30:50
*/
@Service
public class PurchaseReceiptsServiceImpl extends ServiceImpl<PurchaseReceiptsMapper, PurchaseReceipts>
    implements PurchaseReceiptsService{
    @Autowired
    private PurchaseReceiptsMapper purchaseReceiptsMapper;
    @Autowired
    private PurchaseOrdersMapper purchaseOrdersMapper;
    @Autowired
    private DevicesMapper devicesMapper;
    @Autowired
    private ProductsMapper productsMapper;
    @Autowired
    private SuppliersMapper suppliersMapper;
    @Autowired
    private ExamineMapper examineMapper;
    @Autowired
    private ExamineServiceImpl examineService;
    @Autowired
    private ProductsService productsService;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private RemarksMapper remarksMapper;
    @Autowired
    private PaymentBillingMapper paymentBillingMapper;
    @Autowired
    private ExpenseMapper expenseMapper;
    @Autowired
    private PurchasePartMapper purchasePartMapper;
    @Autowired
    private MessageNotificationMapper msgNotificationMapper;
    @Autowired
    private NormalTask normalTask;

    /**
     * 查询采购单列表，指的是审核通过的采购单，时间越新的越靠前
     * @return
     */
    @Override
    public Result purchaseList() {
        // TODO 权限还未做
        //查询采购单列表
        LambdaQueryWrapper<PurchaseOrders> purchaseOrdersLambdaQueryWrapper = new LambdaQueryWrapper<>();
        purchaseOrdersLambdaQueryWrapper.eq(PurchaseOrders::getOrderStatus, "0");   //0审核通过 ,1审核未通过
        purchaseOrdersLambdaQueryWrapper.orderByDesc(PurchaseOrders::getOrderTime);
        //只查10条
        Page<PurchaseOrders> page = new Page<>(1, 10);
        List<PurchaseOrders> ordersList = purchaseOrdersMapper.selectPage(page, purchaseOrdersLambdaQueryWrapper).getRecords();
        if (ordersList != null && ordersList.size() > 0) {
            //添加到map集合中
            Map<Object, PurchaseOrdersVo> mapOne = new HashMap<>();
            for (PurchaseOrders purchaseOrders : ordersList) {
                PurchaseOrdersVo ordersVo = new PurchaseOrdersVo();
                BeanUtils.copyProperties(purchaseOrders, ordersVo);
                mapOne.put(purchaseOrders.getId(),ordersVo);
            }
//            //拿出供应商id集合
//            List<String> collectOne = ordersList.stream().map(PurchaseOrders::getSuppliersId).collect(Collectors.toList());
            //拿出采购产品id
            List<String> collectTwo = ordersList.stream().map(PurchaseOrders::getProductsId).collect(Collectors.toList());
            //查询采购产品
            List<Products> productsList = productsMapper.selectList(new LambdaQueryWrapper<Products>().in(Products::getProductsId, collectTwo));
            for (PurchaseOrders purchaseOrders : ordersList) {
                for (Products products : productsList) {
                    if (purchaseOrders.getProductsId().equals(products.getProductsId())){
                        PurchaseOrdersVo purchaseOrdersVo = mapOne.get(purchaseOrders.getId());
                        BeanUtils.copyProperties(products,purchaseOrdersVo);
                    }
                }
            }
            //查询入库订单
            LambdaQueryWrapper<PurchaseReceipts> purchaseReceiptsLambdaQueryWrapper = new LambdaQueryWrapper<>();
            purchaseReceiptsLambdaQueryWrapper.in(PurchaseReceipts::getProductsId,collectTwo);
            List<PurchaseReceipts> purchaseReceiptsList = purchaseReceiptsMapper.selectList(purchaseReceiptsLambdaQueryWrapper);
            for (PurchaseReceipts receipts : purchaseReceiptsList) {
                PurchaseOrdersVo purchaseOrdersVo = mapOne.get(receipts.getPurchaseOrdersId());
                if (purchaseOrdersVo != null) {
                    BeanUtils.copyProperties(receipts, purchaseOrdersVo);
                }
            }
            //map转list
            List<PurchaseOrdersVo> collect = mapOne.values().stream().collect(Collectors.toList());
            //根据时间排序,时间越新的越靠前
            collect.sort((o1, o2) -> o2.getOrderTime().compareTo(o1.getOrderTime()));
            return Result.success(collect);
        }
        return Result.success(null);
    }

    /**
     * 库管审核入库单
     * @param receiptsId    入库单id
     * @param receiptsStatus    入库单状态
     * @return
     */
    @Override
    public Result adminCheck(String receiptsId, String receiptsStatus) {
        // TODO 权限还未做
        //查询入库单
        PurchaseReceipts purchaseReceipts = purchaseReceiptsMapper.selectById(receiptsId);
        if (purchaseReceipts == null) {
            return Result.error("入库单不存在");
        }
        String title = "";
        if (receiptsStatus.equals("0")){
            purchaseReceipts.setReceiptsStatus(receiptsStatus);
            //查询入库单仓库设备id，通过设备id查询设备信息
            Devices devices = devicesMapper.selectById(purchaseReceipts.getWarehouseDevId());

            //拿采购单金额和设备金额比较，如果采购单金额大于仓库设备金额则修改成财务审核，需要财务审核
            if (devices != null) {
                if(purchaseReceipts.getPrice().compareTo(devices.getPrice()) > 0){
                    purchaseReceipts.setReceiptsStatus("3");
                    title = "价格高于上次价格，等待财务审核通过";
                }else{
                    //小于或等于上次入库价格，直接修改价格，并且库存从已有基础上添加进去
//                    Products productsOne = productsMapper.selectById(purchaseReceipts.getProductsId());
                    devices.setPrice(purchaseReceipts.getPrice());
                    devices.setCount(purchaseReceipts.getNumber()+devices.getCount());
                    title = "入库成功";
                    purchaseReceipts.setReceiptsStatus("0");
                    //修改仓库产品价格和数量
                    int i = devicesMapper.updateById(devices);
                }
                purchaseReceiptsMapper.updateById(purchaseReceipts);
                return Result.success(title);
            }
            //没有设备则直接通过，不需要比较金额
//            Devices devicesOne = new Devices();
            //通过采购产品id查询采购产品信息
            Products productsOne = productsMapper.selectById(purchaseReceipts.getProductsId());
            if (productsOne!=null){
                Devices devicesTwo = new Devices();
                devicesTwo.setPartName(productsOne.getProductsName());
                devicesTwo.setPrice(purchaseReceipts.getPrice());
                devicesTwo.setIsProduct(purchaseReceipts.getIsProduct());
                devicesTwo.setRemark(productsOne.getDescription());
                devicesTwo.setCount(purchaseReceipts.getNumber());
                devicesTwo.setModel(productsOne.getModel());
                devicesTwo.setIsIncludeTax(productsOne.getIsIncludingTax());
                devicesTwo.setImage(productsOne.getImage());
                //是否是产品还是零件
                devicesTwo.setIsProduct(1);
                devicesMapper.insert(devicesTwo);
                purchaseReceipts.setWarehouseDevId(devicesTwo.getId());
            }
            purchaseReceiptsMapper.updateById(purchaseReceipts);
            return Result.success("入库成功");
        }
        purchaseReceipts.setReceiptsStatus(receiptsStatus);
        purchaseReceiptsMapper.updateById(purchaseReceipts);
        return Result.success("入库成功");
    }

    /**
     * 财务审核采购单
     * @param receiptsId
     * @param receiptsStatus
     * @return
     */
    @Override
    public Result financeCheck(String receiptsId, String receiptsStatus) {
        int i = 0;
        //查询当前入库订单是否存在
        PurchaseReceipts purchaseReceipts = purchaseReceiptsMapper.selectById(receiptsId);
        if (purchaseReceipts==null){
            return Result.error("该入库订单不存在");
        }
        purchaseReceipts.setReceiptsStatus(receiptsStatus);
        if(receiptsStatus.equals("0")){
            //查询入库单仓库设备id，通过设备id查询设备信息
            Devices devices = devicesMapper.selectById(purchaseReceipts.getWarehouseDevId());
            devices.setPrice(purchaseReceipts.getPrice());
            devices.setCount(purchaseReceipts.getNumber());
            devices.setIsProduct(purchaseReceipts.getIsProduct());
            //审核通过，修改余额
            i+= devicesMapper.updateById(devices);
        }
        i+= purchaseReceiptsMapper.updateById(purchaseReceipts);
        return i>1? Result.success("审核通过"): Result.error("审核失败");
    }


    /**
     * 申请入库
     * @param purchaseReceiptsDto
     * @return
     */
    @Override
    public Result apply(PurchaseReceiptsDto purchaseReceiptsDto) {
        //TODO 还未做权限校验
        String userid = StpUtil.getLoginId().toString();
        //先查询传入订单名称，型号是否跟订单id名称一致
        PurchaseOrders purchaseOrders = purchaseOrdersMapper.selectById(purchaseReceiptsDto.getPurchaseOrdersId());
        if(purchaseOrders!=null){
            //通过采购订单查询产品
            Products products = productsMapper.selectById(purchaseOrders.getProductsId());
            if (!purchaseReceiptsDto.getProductsName().equals(products.getProductsName()) || !purchaseReceiptsDto.getModel().equals(products.getModel())){
                return Result.error(201,"订单名称或型号不一致");
            }
            //查询该采购订单是否审核通过,如果没有通过提示用户
            if (purchaseOrders.getOrderStatus().equals("1")){
                return Result.error(201,"采购订单审核中,无法申请入库");
            }

            //查询订单是否已入库,或在审核中
            PurchaseReceipts receipts = purchaseReceiptsMapper.selectOne(new LambdaQueryWrapper<PurchaseReceipts>().eq(PurchaseReceipts::getPurchaseOrdersId, purchaseOrders.getId()));
            if (receipts!=null) {
                if (receipts.getReceiptsStatus().equals("0")){
                    return Result.error(201,"该订单已入库,请勿重复提交");
                }
                if (receipts.getReceiptsStatus().equals("1")){
                    return Result.error(201,"该订单待审核,请勿重复提交");
                }
            }
        }


        //采购入库
        PurchaseReceipts purchaseReceipts = new PurchaseReceipts();
        purchaseReceipts.setWarehouseDevId(purchaseOrders.getWarehouseType());
        purchaseReceipts.setIsProduct(1); //采购入库只能是零件，产品的话需要用户直新建产品，并且组装起来
        purchaseReceipts.setId(purchaseReceiptsDto.getReceiptsId());
        purchaseReceipts.setProductsId(purchaseReceiptsDto.getIsProduct());
        purchaseReceipts.setPurchaseOrdersId(purchaseReceiptsDto.getPurchaseOrdersId());
        purchaseReceipts.setReceiptsTime(purchaseReceiptsDto.getStorageTime());
        purchaseReceipts.setReceiptsStatus("1");    //1待审核，0已审核
        purchaseReceipts.setNumber(purchaseReceiptsDto.getNumber());
        purchaseReceipts.setPrice(purchaseReceiptsDto.getPrice());
        purchaseReceipts.setWarehouseDevId(purchaseReceiptsDto.getWarehouseDevId());
        //通过采购订单id查询产品id
        PurchaseOrders orders = purchaseOrdersMapper.selectById(purchaseReceiptsDto.getPurchaseOrdersId());
        if(orders!=null){
            purchaseReceipts.setProductsId(orders.getProductsId());
        }
        Examine examine = examineService.getExamine(userid);
        purchaseReceipts.setManagementId(examine.getManagementId());
        purchaseReceipts.setUserId(examine.getUserId());
        int i = purchaseReceiptsMapper.insert(purchaseReceipts);
        return i>0? Result.success("申请成功") :Result.error("申请失败");
    }


    /**
     * 通过入库id查询入库信息
     * @param receiptsId
     * @return PurchaseInfoVo
     */
    @Override
    public Result purchaseReceiptsInfo(String receiptsId) {

        PurchaseReceipts purchaseReceipts = purchaseReceiptsMapper.selectOne(new LambdaQueryWrapper<PurchaseReceipts>().eq(PurchaseReceipts::getId, receiptsId));
        //入库订单为空
        if (purchaseReceipts==null){
            return Result.success(new PurchaseInfoVo());
        }
        //通过采购订单查询采购订单信息
        PurchaseOrders purchaseOrders = purchaseOrdersMapper.selectById(purchaseReceipts.getPurchaseOrdersId());
        //通过供应商id查询供应商信息
        Suppliers supplier = suppliersMapper.selectById(purchaseOrders.getSuppliersId());
        //通过产品id查询产品信息
        Products products = productsMapper.selectById(purchaseOrders.getProductsId());
        //通过拷贝对象赋值
        PurchaseInfoVo purchaseInfoVo = new PurchaseInfoVo();
        BeanUtils.copyProperties(purchaseOrders,purchaseInfoVo);
        BeanUtils.copyProperties(supplier,purchaseInfoVo);
        BeanUtils.copyProperties(products,purchaseInfoVo);
        purchaseInfoVo.setNumber(purchaseReceipts.getNumber());
        purchaseInfoVo.setPrice(purchaseReceipts.getPrice());
        purchaseInfoVo.setStorageTime(purchaseReceipts.getReceiptsTime());
        purchaseInfoVo.setReceiptsId(purchaseReceipts.getId());
        return Result.success(purchaseInfoVo);
    }


    /**
     * 通过采购订单id，产品类型一键申请入库，
     * @param productIds
     * @return
     */
    @Override
    public Result applyInbound(String productIds) {
        //用户id
        String userid = StpUtil.getLoginId().toString();
        //查询订单是否存在
        PurchaseOrders purchaseOrders = purchaseOrdersMapper.selectById(productIds);
        if (purchaseOrders==null){
            return Result.error(201,"该订单不存在");
        }
        //查询该采购订单是否审核通过,如果没有通过提示用户
        if (purchaseOrders.getOrderStatus().equals("1")){
            return Result.error(201,"采购订单审核中,无法申请入库");
        }

        //查询订单是否已入库,或在审核中
        List<PurchaseReceipts> receipts = purchaseReceiptsMapper.selectList(new LambdaQueryWrapper<PurchaseReceipts>().eq(PurchaseReceipts::getPurchaseOrdersId, productIds));
        if (receipts.size()>0) {
            if (receipts.get(0).getReceiptsStatus().equals("0")){
                    return Result.error(201,"该订单已入库,请勿重复提交");
            }
            if (receipts.get(0).getReceiptsStatus().equals("1") || receipts.get(0).getReceiptsStatus().equals("3")){
                return Result.error(201,"该订单待审核,请勿重复提交");
            }
        }


        //通过订单号去查采购产品订单信息
        Products products = productsMapper.selectById(purchaseOrders.getProductsId());
        //通过名称和型号查询产品是否在仓库中存在,如果存在,把仓库id设置给采购入库
        LambdaQueryWrapper<Devices> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Devices::getModel, products.getModel());
        queryWrapper.eq(Devices::getPartName, products.getProductsName());
        Devices selectOne = devicesMapper.selectOne(queryWrapper);
        PurchaseReceipts purchaseReceipts = new PurchaseReceipts();

        if (selectOne!=null){
            purchaseReceipts.setWarehouseDevId(selectOne.getId());
        }
        Examine examine = examineMapper.selectOne(new LambdaQueryWrapper<Examine>().eq(Examine::getUserId, userid));
        //采购入库
        purchaseReceipts.setIsProduct(1); //采购入库只能是零件，产品的话需要用户直新建产品，并且组装起来
//        purchaseReceipts.setReceiptsId(purchaseReceiptsDto.getReceiptsId());
        purchaseReceipts.setProductsId(purchaseOrders.getProductsId());
        purchaseReceipts.setPurchaseOrdersId(purchaseOrders.getId());
        purchaseReceipts.setReceiptsTime(new Date());
        purchaseReceipts.setReceiptsStatus("1");    //1待审核，0已审核
        purchaseReceipts.setNumber(purchaseOrders.getNumber());
        purchaseReceipts.setPrice(purchaseOrders.getPrice());
        purchaseReceipts.setUserId(examine.getUserId());
        purchaseReceipts.setManagementId(examine.getManagementId());
        //通过采购订单id查询产品id
        int i = purchaseReceiptsMapper.insert(purchaseReceipts);
        return i>0? Result.success("申请成功") :Result.error("申请失败");
    }

    /**
     * 库管采购入库审核
     * @return
     */
    @Override
    public Result selectCheck(Integer page,Integer size) {
        Page<PurchaseOrders> pages = new Page<>(page, size);
        //先查询关联信息表
        String userid = StpUtil.getLoginId().toString();

        LambdaQueryWrapper<PurchaseOrders> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(PurchaseOrders::getManagementId, userid);
        //查询到的信息
        List<PurchaseOrders> purchaseOrdersList = purchaseOrdersMapper.selectPage(pages,queryWrapper).getRecords();

        //查询有几条订单信息
        Long count = purchaseOrdersMapper.selectCount(queryWrapper);
        if (purchaseOrdersList==null || purchaseOrdersList.size()<=0){
            return Result.success(new PurchaseInfoVo());
        }
        //查询供应商信息,拿到供应商名称
        List<String> suppliersIdList = purchaseOrdersList.stream().map(PurchaseOrders::getSuppliersId).collect(Collectors.toList());
        List<Suppliers> suppliersList = suppliersMapper.selectList(new LambdaQueryWrapper<Suppliers>().in(Suppliers::getId, suppliersIdList));
        Map<String, Suppliers> suppliersMap = suppliersList.stream().collect(Collectors.toMap(Suppliers::getId, Function.identity()));
        //有数据，新建Map集合
        Map<Object, PurchaseInfoVo> mapOne = new HashMap<>();
        //拿到采购产品id，查询采购订单信息
        List<String> productsIdList = purchaseOrdersList.stream().map(PurchaseOrders::getProductsId).collect(Collectors.toList());

        //查询的订单，并且拷贝属性
        List<Products> products = productsMapper.selectList(new LambdaQueryWrapper<Products>().in(Products::getProductsId, productsIdList));
        Map<String, Products> productsMap = products.stream().collect(Collectors.toMap(Products::getProductsId, Function.identity()));

        for (PurchaseOrders orders : purchaseOrdersList) {
            PurchaseInfoVo purchaseInVo = new PurchaseInfoVo();
            Products product = productsMap.get(orders.getProductsId());
            if (product != null) {
                BeanUtils.copyProperties(product, purchaseInVo);
            }
            //供应商id相同,就吧名称添加到vo里面
            Suppliers suppliers = suppliersMap.get(orders.getSuppliersId());
            if (suppliers != null) {
                purchaseInVo.setSuppliersName(suppliers.getSuppliersName());
            }
            BeanUtils.copyProperties(orders, purchaseInVo);
            mapOne.put(orders.getId(), purchaseInVo);
        }

        //拿到采购订单id，查询采购入库的有无订单
        List<String> PurchaseOrdersIdList = purchaseOrdersList.stream().map(PurchaseOrders::getId).collect(Collectors.toList());
        List<PurchaseReceipts> purchaseReceiptsList = purchaseReceiptsMapper.selectList(new LambdaQueryWrapper<PurchaseReceipts>().in(PurchaseReceipts::getPurchaseOrdersId,PurchaseOrdersIdList));
        //如果有值，则进行进行添加到VO
        if (purchaseReceiptsList!=null ||purchaseReceiptsList.size()>0){
            for (PurchaseReceipts receipts : purchaseReceiptsList) {
                PurchaseInfoVo infoVo = mapOne.get(receipts.getPurchaseOrdersId());
                infoVo.setReceiptsStatus(receipts.getReceiptsStatus());
                infoVo.setReceiptsTime(receipts.getReceiptsTime());
            }
        }

        List<PurchaseInfoVo> purchaseInfoVoList = new ArrayList<>(mapOne.values());
        //根据时间排序,时间越新，排序越靠前
        purchaseInfoVoList.sort((o1, o2) -> o2.getOrderTime().compareTo(o1.getOrderTime()));
        PurchasePageInfoVo purchasePageInfoVo = new PurchasePageInfoVo();
        purchasePageInfoVo.setPurchaseInfoVoList(purchaseInfoVoList);
        purchasePageInfoVo.setTotal(count);
        return Result.success(purchasePageInfoVo);
    }


    /**
     * 库管审核采购订单
     * @return
     */
    @Override
    public Result applyCheck(String receiptsId, String status) {
        //TODO 查询是否有权限
        //查询是否存在该订单
        PurchaseOrders receipts = purchaseOrdersMapper.selectById(receiptsId);
        if (receipts==null){
            return Result.error("该订单不存在");
        }
        receipts.setOrderStatus(status);
        purchaseOrdersMapper.updateById(receipts);
        return Result.success("操作成功");
    }

    @Override
    public Result getPurchaseReceiptsList(PurchaseReceiptsDto purchaseReceiptsDto) {
        if (purchaseReceiptsDto == null ||
                (purchaseReceiptsDto.getCurrentPage() == null || purchaseReceiptsDto.getPageSize() == null)){
            return new Result(HttpStatus.BAD_REQUEST,"缺少参数");
        }
        Page<PurchaseReceipts> purchaseReceiptsPage = new Page<>(purchaseReceiptsDto.getCurrentPage(),purchaseReceiptsDto.getPageSize());
        // 条件查询
        LambdaQueryWrapper<PurchaseReceipts> purchaseReceiptsLQW = new LambdaQueryWrapper<>();
        purchaseReceiptsLQW.orderByDesc(PurchaseReceipts::getReceiptsTime);
        if (purchaseReceiptsDto.getReceiptsStatus() != null){
            purchaseReceiptsLQW.eq(PurchaseReceipts::getReceiptsStatus,purchaseReceiptsDto.getReceiptsStatus());
        }
        List<PurchaseReceipts> purchaseReceiptsList = purchaseReceiptsMapper.selectPage(purchaseReceiptsPage, purchaseReceiptsLQW).getRecords();
        if (purchaseReceiptsList.size() == 0){
            List<PurchaseReceiptsVo> purchaseReceiptsVoList = new ArrayList<>();
            Map<String,Object> map = new HashMap<>();
            map.put("total",purchaseReceiptsPage.getTotal());
            map.put("purchaseReceiptsVoList",purchaseReceiptsVoList);
            return Result.success("查询成功",map);
        }

        List<String> purchaseReceiptsIdList = purchaseReceiptsList.stream().map(PurchaseReceipts::getId).collect(Collectors.toList());
//        // 入库map，根据入库id获取入库对象
//        Map<String,PurchaseReceipts> purchaseReceiptsMap = purchaseReceiptsList.stream().collect(Collectors.toMap(PurchaseReceipts::getPurchaseOrdersId,p ->purchaseReceiptsList.stream()
//                .filter(purchaseReceipts -> purchaseReceipts.getPurchaseOrdersId().equals(p.getPurchaseOrdersId()))
//                .findFirst()
//                .orElse(null)));
        // 用户map
        Set<String> userIdList = purchaseReceiptsList.stream().map(PurchaseReceipts::getUserId).collect(Collectors.toSet());
        Set<String> managementIdList = purchaseReceiptsList.stream().map(PurchaseReceipts::getManagementId).collect(Collectors.toSet());
        userIdList.addAll(managementIdList);
        LambdaQueryWrapper<User> userLQW = new LambdaQueryWrapper<>();
        userLQW.in(User::getId,userIdList);
        List<User> userList = userMapper.selectList(userLQW);
        // 根据用户id获取用户对象
        Map<String, User> stringUserMap = userList.stream().collect(Collectors.toMap(User::getId,Function.identity()));
        // 入库备注
        LambdaQueryWrapper<Remarks> remarksLQW = new LambdaQueryWrapper<>();
        remarksLQW.in(Remarks::getQueryId,purchaseReceiptsIdList);
        List<Remarks> remarksList = remarksMapper.selectList(remarksLQW);
        // 根据入库id获取备注对象
        Map<String, Remarks> remarksMap = remarksList.stream().collect(Collectors.toMap(Remarks::getQueryId, r -> remarksList.stream()
                .filter(remarks -> remarks.getQueryId().equals(r.getQueryId()))
                .findFirst()
                .orElse(null)));

        // 根据采购id集合获取采购订单列表
        List<String> purchaseOrdersIdList = purchaseReceiptsList.stream().map(PurchaseReceipts::getPurchaseOrdersId).collect(Collectors.toList());
        List<PurchaseOrders> purchaseOrdersList = purchaseOrdersMapper.selectBatchByIdWithDelete(purchaseOrdersIdList);
        // 根据采购订单id，获取采购订单对象
        Map<String, PurchaseOrders> purchaseOrdersMap = purchaseOrdersList.stream().collect(Collectors.toMap(PurchaseOrders::getId, Function.identity()));
        // 根据采购订单列表，获取供应商、采购人、采购产品的map集合
        Map<String, Object> keyMap = productsService.getKeyMap(purchaseOrdersList);
        Map<String,Suppliers> suppliersMap = (Map<String, Suppliers>) keyMap.get("suppliersMap");
        Map<String, User> userMap = (Map<String, User>) keyMap.get("userMap");
        Map<String, List<PurchasePartDto>> purchasePartMap = (Map<String, List<PurchasePartDto>>) keyMap.get("purchasePartMap");

        List<PurchaseReceiptsVo> purchaseReceiptsVoList = new ArrayList<>();
        for (PurchaseReceipts purchaseReceipts : purchaseReceiptsList){
            PurchaseOrders purchaseOrders = purchaseOrdersMap.get(purchaseReceipts.getPurchaseOrdersId());
            PurchaseReceiptsVo purchaseReceiptsVo = new PurchaseReceiptsVo();
            // id
            purchaseReceiptsVo.setId(purchaseReceipts.getId());
            // 采购订单ID
            purchaseReceiptsVo.setPurchaseOrdersId(purchaseOrders.getId());
            // 供应商名称
            purchaseReceiptsVo.setSuppliersName(suppliersMap.get(purchaseOrders.getSuppliersId()).getSuppliersName());
            // 采购人姓名
            purchaseReceiptsVo.setUserName(userMap.get(purchaseOrders.getUserId()).getNickName());
            // 总金额
            purchaseReceiptsVo.setPrice(purchaseOrders.getPrice());
            // 零件列表
            purchaseReceiptsVo.setParts(purchasePartMap.get(purchaseOrders.getId()));
            // 结款方式
            purchaseReceiptsVo.setPaymentMethod(purchaseOrders.getPaymentMethod());
            // 入库日期
            purchaseReceiptsVo.setReceiptsTime(DateUtils.YMDHMSFormat(purchaseReceipts.getReceiptsTime()));
            // 申请用户姓名
            String userId = purchaseReceipts.getUserId();
            purchaseReceiptsVo.setNickName(stringUserMap.get(userId).getNickName());
            // 审核人姓名
            if (purchaseReceipts.getManagementId() != null){
                String managementId = purchaseReceipts.getManagementId();
                purchaseReceiptsVo.setManagementName(stringUserMap.get(managementId).getNickName());
            }
            // 审核时间
            if (purchaseReceipts.getApplyTime() != null){
                purchaseReceiptsVo.setApplyTime(DateUtils.YMDHMSFormat(purchaseReceipts.getApplyTime()));
            }
            // 入库状态
            purchaseReceiptsVo.setReceiptsStatus(purchaseReceipts.getReceiptsStatus());
            // 入库备注
            if (remarksMap.containsKey(purchaseReceipts.getId())){
                purchaseReceiptsVo.setRemarks(remarksMap.get(purchaseReceipts.getId()).getRemarkContent());
            }
            purchaseReceiptsVoList.add(purchaseReceiptsVo);
        }
        Map<String,Object> map = new HashMap<>();
        map.put("total",purchaseReceiptsPage.getTotal());
        map.put("purchaseReceiptsVoList",purchaseReceiptsVoList);
        return Result.success("查询成功",map);
    }

    @Override
    @Transactional
    public Result applyPurchaseReceipts(PurchaseReceiptsDto purchaseReceiptsDto) {
        if (purchaseReceiptsDto == null){
            return new Result(HttpStatus.BAD_REQUEST,"参数为空(purchaseReceiptsDto is null)");
        }
        if ( purchaseReceiptsDto.getId() == null || purchaseReceiptsDto.getId().isEmpty()){
            return new Result(HttpStatus.BAD_REQUEST,"参数为空(purchaseReceiptsDto[id] is null)");
        }
        User user = userMapper.selectById(StpUtil.getLoginIdAsString());
        if (!user.getRoleId().equals(RoleEnum.ROLE_1.getCodeToString()) &&
                !user.getRoleId().equals(RoleEnum.ROLE_5.getCodeToString())){
            return new Result(HttpStatus.FORBIDDEN,"无权访问");
        }
        // 查询是否有该入库申请
        PurchaseReceipts purchaseReceipts = purchaseReceiptsMapper.selectById(purchaseReceiptsDto.getId());
        if (purchaseReceipts == null){
            return new Result(HttpStatus.BAD_REQUEST,"该入库申请不存在");
        }

        // 审核人
        purchaseReceipts.setManagementId(user.getId());
        // 审核时间
        purchaseReceipts.setApplyTime(new Date());
        // 状态
        purchaseReceipts.setReceiptsStatus(purchaseReceiptsDto.getReceiptsStatus());

        // 更新数据
        purchaseReceiptsMapper.updateById(purchaseReceipts);

        // 判断是否通过
        if (purchaseReceiptsDto.getReceiptsStatus().equals("0")){
            // 通过则生成采购账单
            // 判断结款方式
            PurchaseOrders purchaseOrders = purchaseOrdersMapper.selectById(purchaseReceipts.getPurchaseOrdersId());
            if (purchaseOrders.getPaymentMethod() == 0){
                // 现金结款，创建报销单
                Expense expense = new Expense();
                expense.setPurchaseId(purchaseOrders.getId());
                // 申请人
                expense.setUserId(purchaseOrders.getUserId());
                // 报销金额
                expense.setPrice(purchaseOrders.getPrice());
                // 报销说明
                expense.setInfo("采购订单编号："+purchaseOrders.getId());
                // 状态，待审核
                expense.setStatus(0);
                // 插入数据
                expenseMapper.insert(expense);
                // 创建消息通知
                // 查管理员角色
                LambdaQueryWrapper<User> userLQW = new LambdaQueryWrapper<>();
                userLQW.eq(User::getState, BaseEnum.USER_INCUMBENCY.getCodeInt())
                        .eq(User::getRoleId,RoleEnum.ROLE_1.getCodeToString());
                List<User> userList = userMapper.selectList(userLQW);
                User user1 = userMapper.selectById(expense.getUserId());
                if (!userList.isEmpty()){
                    List<MessageNotification> msgList = new ArrayList<>();
                    for (User admin : userList){
                        MessageNotification msg = new MessageNotification();
                        msg.setId(UUID.randomUUID().toString().replaceAll("-",""));
                        // 标题
                        msg.setTitle("有新的报销申请待审批");
                        // 内容
                        String content = user1.getNickName()+"申请报销"+expense.getPrice()+"元";
                        msg.setContent(content);
                        // 发布人为申请人
                        msg.setPublisherId(user1.getId());
                        // 接收人为管理员
                        msg.setReceiverId(admin.getId());
                        // 关联id
                        msg.setRelevanceId(expense.getId());
                        // 类型为报销管理
                        msg.setMsgType(8);
                        // 子菜单1报销列表
                        msg.setSubmenu(1);
                        // 状态为待处理
                        msg.setStatus(0);
                        msg.setCreateTime(new Date());
                        msgList.add(msg);
                    }
                    msgNotificationMapper.insertBatch(msgList);
                }
            }else {
                // 月结，直接创建账单
                PaymentBilling paymentBilling = new PaymentBilling();
                // 采购id
                paymentBilling.setOrderId(purchaseReceipts.getPurchaseOrdersId());
                // 应付金额
                paymentBilling.setAmountPayable(purchaseOrders.getPrice());
                // 应付日期，月结则在月底前
                // 本月最后一天
                LocalDate currentDate = LocalDate.now();
                LocalDate lastDayOfMonth = currentDate.withDayOfMonth(currentDate.lengthOfMonth());
                paymentBilling.setDatePayable(lastDayOfMonth);
                // 账单状态，待付款
                paymentBilling.setBillsStatus(0);
                // 插入数据
                paymentBillingMapper.insert(paymentBilling);
            }

            // 给库存加上对应的数量
            // 根据设备id查询设备，并处理成map集合
            LambdaQueryWrapper<PurchasePart> purchasePartLQW = new LambdaQueryWrapper<>();
            purchasePartLQW.eq(PurchasePart::getPurchaseId,purchaseOrders.getId());
            List<PurchasePart> purchasePartList = purchasePartMapper.selectList(purchasePartLQW);
            List<String> partIdList = purchasePartList.stream().map(PurchasePart::getPartId).collect(Collectors.toList());
            LambdaQueryWrapper<Devices> devicesLQW = new LambdaQueryWrapper<>();
            devicesLQW.in(Devices::getId,partIdList);
            List<Devices> devicesList = devicesMapper.selectList(devicesLQW);
            Map<String, Devices> devicesMap = devicesList.stream().collect(Collectors.toMap(Devices::getId, d -> devicesList.stream()
                    .filter(devices -> devices.getId().equals(d.getId()))
                    .findFirst()
                    .orElse(null)));
            // 给设备添加对应数量
            List<Devices> selectDevicesList = new ArrayList<>();
            for (PurchasePart purchasePart : purchasePartList){
                if (devicesMap.containsKey(purchasePart.getPartId())){
                    Devices devices = devicesMap.get(purchasePart.getPartId());
                    if (devices.getCount() <= 0){
                        // 库存0，更新采购单价和运输费
                        devices.setCost(purchasePart.getPurchasePrice());
                        devices.setFreight(purchasePart.getFreight());
                    }
                    devices.setCount(devices.getCount()+purchasePart.getPartCount());
                    devices.setSupId(purchaseReceiptsDto.getSupName());
                    selectDevicesList.add(devices);
                }
            }
            // 更新数据
            if (selectDevicesList.size() > 0){
                devicesMapper.updateCountBatchById(selectDevicesList);
                Set<String> devicesIdList = selectDevicesList.stream().map(Devices::getId).collect(Collectors.toSet());
                normalTask.updateProductPrice(devicesIdList);
            }
        }
        String status;
        if (purchaseReceiptsDto.getReceiptsStatus().equals("0")){
            // 已通过
            status = "已通过";
        }else {
            // 未通过
            status = "未通过";
        }
        MessageNotification msg = new MessageNotification();
        // 标题
        String title = "一键入库申请"+status;
        msg.setTitle(title);
        // 内容
        String content = "您的一键入库申请"+status;
        msg.setContent(content);
        // 发布人为审核人
        msg.setPublisherId(user.getId());
        // 接收人为申请人
        msg.setReceiverId(purchaseReceipts.getUserId());
        // 关联id
        msg.setRelevanceId(purchaseReceipts.getId());
        // 类型为仓库管理
        msg.setMsgType(6);
        // 子菜单为1采购管理
        msg.setSubmenu(1);
        // 状态为待处理
        msg.setStatus(0);
        msgNotificationMapper.insert(msg);
        return Result.success("操作成功");
    }

    @Override
    public Result deletePurchaseReceipts(PurchaseReceiptsDto purchaseReceiptsDto) {
        if (purchaseReceiptsDto == null || purchaseReceiptsDto.getId() == null || purchaseReceiptsDto.getId().isEmpty()){
            return new Result(HttpStatus.BAD_REQUEST,"缺少参数");
        }
        purchaseReceiptsMapper.deleteById(purchaseReceiptsDto.getId());
        return Result.success("删除成功");
    }
}



